package com.aichan.aibi.utils;

import cn.hutool.core.util.SerializeUtil;
import com.github.benmanes.caffeine.cache.Cache;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;

import java.util.function.Function;

/**
 * @author mengyu
 * @date 2024/05/29 16:36
 */
@Component
public class CaffeineCache {
    @Resource
    private Cache<String, byte[]> cache;

    /**
     * 向缓存中存放数据
     * @param key 键
     * @param value 值
     * @param <T> 存放的对象的类型
     */
    public <T> void put(String key, T value){
        byte[] serializedObject = SerializeUtil.serialize(value);
        cache.put(key,serializedObject);
    }

    /**
     * 从缓存中取出数据
     * @param key 键
     * @param cls 数据的类型
     * @return 对应数据
     */
    public <T> T get(String key, Class<T> cls) {
        byte[] ifPresent = cache.getIfPresent(key);
        if (ifPresent == null)
            return null;
        return cls.cast(SerializeUtil.deserialize(ifPresent));
    }

    /**
     * 带有CacheLoader的get，注意传入的Function返回的类型需是序列化后的byte[]
     * @param key 键
     * @param cls 数据的类型
     * @param function 当发现在缓存中没有此数据时执行的方法
     * @return 对应数据
     */
    public <T> T get(String key, Class<T> cls, Function<String,byte[]> function) {
        byte[] bytes = cache.get(key, function);
        return cls.cast(SerializeUtil.deserialize(bytes));
    }

    /**
     * 删除缓存中的数据
     * @param key 键
     */
    public void remove(String key){
        cache.invalidate(key);
    }

    /**
     * 删除缓存中的数据
     * @param iterable 可迭代的键
     */
    public void remove(Iterable<? extends String> iterable){
        cache.invalidateAll(iterable);
    }

    /**
     * 清空缓存
     */
    public void clean(){
        cache.invalidateAll();
    }
}
